package com.springsource.boot.autoConfig2;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import com.springsource.a10SpringAOP.A101;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;

public class A41_2 {

    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        StandardEnvironment environment = new StandardEnvironment();
        environment.getPropertySources().addLast(new SimpleCommandLinePropertySource("--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/quantitative_trading " +
                "--spring.datasource.username=root " +
                " --spring.datasource.password=root" +
                "--spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver"));
        context.setEnvironment(environment);
        context.registerBean("config", Config.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.refresh();

        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

    }

    @Configuration // 自己的配置类
    @EnableAutoConfiguration
    static class Config {

    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.TYPE})
    @Conditional(MyCondition.class)
    @interface ConditionalOnClass {
        boolean exists();
        String className();
    }

    static class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionalOnClass.class.getName());
            String className = annotationAttributes.get("className").toString();
            Boolean exists = (Boolean) annotationAttributes.get("exists");
            boolean present = ClassUtils.isPresent(className, null);
            return present == exists;
        }
    }


    @Configuration // 第三方配置类
    @ConditionalOnClass(exists = true, className = "cn.hutool.core.collection.CollUtil")
    static class AutoConfiguration1 {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }
    }


    static class Bean1 {}

    @Configuration // 第三方配置类
    @ConditionalOnClass(exists = false, className = "cn.hutool.core.collection.CollUtil")
    static class AutoConfiguration2 {
        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }


    static class Bean2 {}
}
